//By Rob Bateman and Moncef Slimane

#include <iostream>
#include <GL/glut.h>
//#include "fileload.h"
#include "load_ini.h"
#include "Main.h"
#include "font.h"

#define DEV
#define __VERSION__ "0.1"
#define __REV__ "1"

//  Represents the subwindow id
int subwindow_1;
int wscreen_width=640; // Width
int wscreen_height=480; // Height
int hWw = wscreen_width;
int hHw = wscreen_height;

int main_window;

int mainWindow, subWindow1,subWindow2,subWindow3, border;

// gap between subwindows
#define GAP  25
float main_window_x;
float main_window_y;

float main_window_w = hWw + GAP * 2;
float main_window_h = hHw + 64 + GAP * 3;

//  define the window position on screen
float subwindow1_x = GAP;
float subwindow1_y = GAP;

//  variables representing the window size
float subwindow1_w = hWw;
float subwindow1_h = hHw;

float zoom = 15.0f;
float rotx = 0;
float roty = 0.001f;
float tx = 0;
float ty = 0;
int lastx=0;
int lasty=0;
unsigned char Buttons[3] = {0};


//-------------------------------------------------------------------------------
/// \brief	Initialises the openGL scene
///
void centerOnScreen()
{
	main_window_x = (glutGet (GLUT_SCREEN_WIDTH) - main_window_w)/2;
	main_window_y = (glutGet (GLUT_SCREEN_HEIGHT) - main_window_h)/2;
}

void Init() 
{
	FILE *l_file; // File pointer
	glEnable(GL_DEPTH_TEST);
		fprintf( stdout, "Windows Instalzing,Loading Configurations. \n");
    LoadINI("config.ini");


	
	wscreen_width=LoadINI_GetInt("config.ini","screen settings","wwidth",640);
	wscreen_height=LoadINI_GetInt("config.ini","screen settings","wheight",480);
	hWw = wscreen_width/2;
	hHw = wscreen_height/2;



}

//-------------------------------------------------------------------------------
/// \brief	Draws the scene
/// 
/// Playing as quad for Quad Window support
void display1()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	
	glLoadIdentity();
	
	glTranslatef(0,0,-zoom);
	glTranslatef(tx,ty,0);
	glRotatef(rotx,1,0,0);
	glRotatef(roty,0,1,0);	
	
	// draw grid
	glBegin(GL_LINES);
	for(int i=-10;i<=10;++i) {
		glVertex3f(i,0,-10);
		glVertex3f(i,0,10);

		glVertex3f(10,0,i);
		glVertex3f(-10,0,i);
	}
	glEnd();
	
		//drawtruck();

	
	glutSwapBuffers();
}
void display2()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	
	glLoadIdentity();
	
	glTranslatef(0,0,-zoom);
	glTranslatef(tx,ty,0);
	glRotatef(rotx,1,0,0);
	glRotatef(roty,0,1,0);	
	
	// draw grid
	glBegin(GL_LINES);
	for(int i=-10;i<=10;++i) {
		glVertex3f(i,0,-10);
		glVertex3f(i,0,10);

		glVertex3f(10,0,i);
		glVertex3f(-10,0,i);
	}
	glEnd();
	
	//drawtruck();
	
	glutSwapBuffers();
}
void display3()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	
	glLoadIdentity();
	
	glTranslatef(0,0,-zoom);
	glTranslatef(tx,ty,0);
	glRotatef(rotx,1,0,0);
	glRotatef(roty,0,1,0);	
	
	// draw grid
	glBegin(GL_LINES);
	for(int i=-10;i<=10;++i) {
		glVertex3f(i,0,-10);
		glVertex3f(i,0,10);

		glVertex3f(10,0,i);
		glVertex3f(-10,0,i);
	}
	glEnd();
	
		//drawtruck();
	
	glutSwapBuffers();
}
void display4()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	
	glLoadIdentity();
	
	glTranslatef(0,0,-zoom);
	glTranslatef(tx,ty,0);
	glRotatef(rotx,1,0,0);
	glRotatef(roty,0,1,0);	
	
	// draw grid
	glBegin(GL_LINES);
	for(int i=-10;i<=10;++i) {
		glVertex3f(i,0,-10);
		glVertex3f(i,0,10);

		glVertex3f(10,0,i);
		glVertex3f(-10,0,i);
	}
	glEnd();
	
		//drawtruck();

	glutSwapBuffers();
}

//-------------------------------------------------------------------------------
/// \brief	Called when the screen gets resized
/// \param	w	-	the new width
/// \param	h	-	the new height
/// 
void reshape1(int w, int h)
{
	// prevent divide by 0 error when minimised
	if(w==0) 
		h = 1;

	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45,(float)w/h,0.1,100);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void reshape2(int w, int h)
{
	// prevent divide by 0 error when minimised
	if(w==0) 
		h = 1;

	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45,(float)w/h,0.1,100);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void reshape3(int w, int h)
{
	// prevent divide by 0 error when minimised
	if(w==0) 
		h = 1;

	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45,(float)w/h,0.1,100);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
void reshape4(int w, int h)
{
	// prevent divide by 0 error when minimised
	if(w==0) 
		h = 1;

	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45,(float)w/h,0.1,100);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

//-------------------------------------------------------------------------------
//
void Motion(int x,int y)
{
	int diffx=x-lastx;
	int diffy=y-lasty;
	lastx=x;
	lasty=y;

	if( Buttons[0] && Buttons[1] )
	{
		zoom -= (float) 0.05f * diffx;
	}
	else
		if( Buttons[0] )
		{
			rotx += (float) 0.5f * diffy;
			roty += (float) 0.5f * diffx;		
		}
		else
			if( Buttons[1] )
			{
				tx += (float) 0.05f * diffx;
				ty -= (float) 0.05f * diffy;
			}
			glutPostRedisplay();
}

//-------------------------------------------------------------------------------
//
void Mouse(int b,int s,int x,int y)
{
	lastx=x;
	lasty=y;
	switch(b)
	{
	case GLUT_LEFT_BUTTON:
		Buttons[0] = ((GLUT_DOWN==s)?1:0);
		break;
	case GLUT_MIDDLE_BUTTON:
		Buttons[1] = ((GLUT_DOWN==s)?1:0);
		break;
	case GLUT_RIGHT_BUTTON:
		Buttons[2] = ((GLUT_DOWN==s)?1:0);
		break;
	default:
		break;		
	}
	// Wheel reports as button 3(scroll up) and button 4(scroll down)
   if ((b == 3) || (b == 4)) // It's a wheel event
   {
       // Each wheel event reports like a button click, GLUT_DOWN then GLUT_UP
       if (s == GLUT_UP) return; // Disregard redundant GLUT_UP events
       //printf("Scroll %s At %d %d\n", (b == 3) ? "Up" : "Down", x, y);
	  // zoom -= (float) 0.05f * diffx;
   }
#if defined(DEBUG)
   else
   {  // normal button event
       printf("Button %s At %d %d\n", (s == GLUT_DOWN) ? "Down" : "Up", x, y);
   }
#endif
	glutPostRedisplay();
}

//-------------------------------------------------------------------------------
void background()
{
fprintf( stdout, "Instalzing Background. \n");
if (hWw < GAP * 4 || hHw < GAP * 6)
{
    glutSetWindow (main_window);
    glutReshapeWindow (main_window_w, main_window_h);
    return;
}
glutReshapeFunc(reshape1);
glutSwapBuffers();
fprintf( stdout, "Done. \n");
}

void window1()
{
fprintf( stdout, "Instalzing Window X. \n");
subwindow_1 = glutCreateSubWindow (main_window, GAP, GAP, subwindow1_w, subwindow1_h);
glutSetWindow (subwindow_1);
glutDisplayFunc(display1);
glutPositionWindow (subwindow1_x, subwindow1_y);
glutReshapeWindow (subwindow1_w, subwindow1_h);
glutReshapeFunc(reshape1);
glutMouseFunc(Mouse);
glutMotionFunc(Motion);
fprintf( stdout, "Done. \n");
}

void window2()
{
	/*
fprintf( stdout, "Instalzing Window Y. \n");

glutInitWindowSize(hWw, hHw);
glutInitWindowPosition(320, 20);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
Window2 = glutCreateWindow("Y");
glutDisplayFunc(display2);
	glutReshapeFunc(reshape2);
	glutMouseFunc(Mouse);
fprintf( stdout, "Done. \n");
*/
}

void window3()
{
	/*
fprintf( stdout, "Instalzing Window Z. \n");

glutInitWindowSize(hWw, hHw);
glutInitWindowPosition(640, 20);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
Window3 = glutCreateWindow("Z");
glutDisplayFunc(display3);
	glutReshapeFunc(reshape3);
	glutMouseFunc(Mouse);
fprintf( stdout, "Done. \n");
*/
}

void threeDview()
{
	/*
fprintf( stdout, "Instalzing 3D View. \n");

glutInitWindowSize(hWw, hHw);
glutInitWindowPosition(1280, 20);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
TDview = glutCreateWindow("3D View");
glutDisplayFunc(display4);
	glutReshapeFunc(reshape4);
	glutMouseFunc(Mouse);
	glutMotionFunc(Motion);
	
fprintf( stdout, "Done. \n");
*/
}

void tools()
{
	/*
fprintf( stdout, "Instalzing Tools. \n");

fprintf( stdout, "Failed. \n");
*/
}
void Mainw()
{
centerOnScreen();
glutInitWindowSize(main_window_w, main_window_h); 
glutInitWindowPosition(main_window_x, main_window_y); 
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
main_window = glutCreateWindow("RoREditor -" __VERSION__);
glutDisplayFunc(background);

subwindow1_w = (subwindow1_w * (hWw-GAP*2.0))/(main_window_w-GAP*2.0);
subwindow1_h = (subwindow1_h * (hHw-GAP*3.0))/(main_window_h-GAP*3.0);
window1();
window2();
window3();
tools();
threeDview();
}
//-------------------------------------------------------------------------------
///
int main(int argc,char** argv)
{
    freopen( "log.txt", "w", stdout );
	freopen( "log.txt", "w", stderr );

  //Informations about the tool
  printf("ROREDITOR -> Ver_" __VERSION__" Rev_" __REV__ " \n");
  #ifdef DEBUG
  printf("Debug Mode\n");
  #else
  printf("Relase Mode\n");
  #endif
  #ifdef DEV
  printf("Devlopper/Unstable Relase\n");
  #else
  printf("Public/Stable Relase\n");
  #endif

    fprintf( stdout, "Instalzing Main System. \n");
	fprintf( stdout, "Instalzing GLUT. \n");
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
	fprintf( stdout, "Done. \n");
	//Init
	Mainw();
	Init();
	//Out logs
	fprintf( stdout, "Done Instalzing Main System. \n");
	fprintf( stdout, "Entring GLUT Main Loop. \n");

	glutMainLoop();
}

























